package controllers

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	"golang.org/x/crypto/bcrypt"
	"log"
	"net/http"
	"oceanLearn/common"
	"oceanLearn/dto"
	"oceanLearn/models"
	resp "oceanLearn/response"
	"oceanLearn/util"
)

func UserRegister(c *gin.Context) {
	db := common.GetDB()

	//获取参数
	/*
		因为通过axios 发送的是JSON 格式 和 通过表单发送的FormData格式不同

	1.form格式，将Content-Type类型设置为application/x-www-form-urlencode，
	POST请求时将data序列化,提交的数据会按照 key1=val1&key2=val2 的方式进行编码，key 和 val 都进行了 URL 转码

	2.json格式，有时候后台需要body传送的是json数据，将Content-Type类型设置为application/json，注意POST请求时data不要序列化

	 */
	var requestUser = models.User{}
	json.NewDecoder(c.Request.Body).Decode(&requestUser)

	//获取参数
	username := requestUser.Username
	password := requestUser.Password
	tel := requestUser.Tel
/*
	//获取参数
	username := c.PostForm("username")
	password := c.PostForm("password")
	tel := c.PostForm("tel")
*/
	//数据验证
	log.Println(tel, len(tel))
	if len(tel) != 11 {
		resp.Response(c,http.StatusUnprocessableEntity ,422,nil,"电话号码只能为11位!!!")
		return
	}

	if len(password) < 6 {
		resp.Response(c,http.StatusUnprocessableEntity ,422,nil,"密码不能少于6位!!!")
		return
	}

	//如果没有传值，给一个10位的随机字符串
	if len(username) == 0 {
		username = util.RandomString(10)
	}

	log.Println(username, password, tel)

	//判断手机号是否存在
	if isTelExist(db, tel) {
		resp.Response(c,http.StatusUnprocessableEntity ,422,nil,"手机号码已经被注册啦!!!")
		return
	}

	//创建用户
	hashPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	if err != nil {
		resp.Response(c,http.StatusUnprocessableEntity ,500,nil,"加密错误!!!")
	}

	newUser := models.User{
		Username: username,
		Tel:      tel,
		Password: string(hashPassword),
	}
	db.Create(&newUser)

	//发放token
	token, err := common.ReleaseToken(newUser)
	if err != nil {
		resp.Response(c,http.StatusBadRequest ,500,nil,"系统异常!!!")
		return
	}
	//返回结果
	resp.Response(c,http.StatusOK ,500,gin.H{"token": token},"注册成功!")
}

func Login(c *gin.Context) {
	db := common.GetDB()

	//var requestUser = models.User{}
	//json.NewDecoder(c.Request.Body).Decode(&requestUser)
	//log.Println(requestUser)

	// 获取参数
	tel := c.PostForm("tel")
	password := c.PostForm("password")

	// 数据验证
	if len(tel) != 11 {
		resp.Response(c,http.StatusUnprocessableEntity ,422,nil,"电话号码只能为11位!!!")
		return
	}

	if len(password) < 6 {
		resp.Response(c,http.StatusUnprocessableEntity ,422,nil,"密码不能少于6位!!!")
		return
	}

	//判断手机号是否存在
	var user models.User
	db.Where("tel=?", tel).First(&user)
	if user.ID == 0 {
		resp.Response(c,http.StatusUnprocessableEntity ,422,nil,"用户不存在!!!")
		return
	}

	//判断密码是否正确
	if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
		resp.Response(c,http.StatusBadRequest ,400,nil,"密码错误!!!")
		return
	}

	//发放token
	token, err := common.ReleaseToken(user)
	if err != nil {
		resp.Response(c,http.StatusBadRequest ,500,nil,"系统异常!!!")
		return
	}

	//返回结果
	resp.Response(c,http.StatusOK ,200,gin.H{"token": token},"登陆成功!!!")
}

func UserInfo(c *gin.Context) {
	user, _ := c.Get("user")
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"data_0": gin.H{"user":user},
		"data_dto": gin.H{"user": dto.ToUserDto(user.(models.User))},//类型断言 相当于强制类型转化，在这里相当于把interface{}(user)转化为了models.User(user)类型
	})
}

func isTelExist(db *gorm.DB, tel string) bool {
	var user models.User
	db.Where("tel=?", tel).First(&user)
	if user.ID != 0 {
		return true
	}
	return false
}
